package com.trainsmart.smartmvc
{
	import flash.display.DisplayObjectContainer;
	
	import mx.core.UIComponent;
	
	public class Context 
	{
		
		
		public var _contextId:Number=Util.UniqueId;		
		public var attachUI:UIComponent;
		public var registered:Boolean = false;
		
		private var _cache:Array = new Array();
		public var views:Array = new Array();
		public var controls:Array = new Array();
		public var models:Array = new Array();
		
		
		public var initRuns:Array = new Array();	
		
				
		public function Context(ui:UIComponent)
		{
			attachUI = ui;
			ContextManager.getInstance().registerContext(this);
		}
		
		public function registerContext(contextId:Number):void{
			if(registered) throw new  Error("register Id error in context");
			
			ContextManager.getInstance().unRegisterContext(_contextId);			
			_contextId = contextId;
		    ContextManager.getInstance().registerContext(this);
		    registered = true;
		}
		
		public function getContextId():Number
		{
			
			return _contextId;
		}
		
		
		public function registerView(viewId:String, view:SmartForm):void{
			var v:SmartForm = views[viewId] as SmartForm;
			if(v!=null)
			 throw new Error("duplicate registering view in Context");
			views[viewId] = view;
		}
		
		public function existingView(viewId:String):Boolean{
			var v:SmartForm = views[viewId] as SmartForm;
			return (v!=null);
		}
		
		public function getView(viewId:String):SmartForm{
			var v:SmartForm = views[viewId] as SmartForm;
			if(v==null)
			 throw new Error("haven't registered component in Context");
			return v;
		}
		
		public function unRegisterView(viewId:String):void{
			delete views[viewId];
		}
		
		/**
		 * 
		 */
		public function registerControl(controlId:String, control:IControl, autorun:Boolean=false):void{
			var _control:IControl = controls[controlId] as IControl;
			if(_control!=null)
			 throw new Error("duplicate registering control in Context");
			controls[controlId] = control;
			if(autorun)
			  this.initRuns.push(controlId);
		}
		public function existingControl(controlId:String):Boolean{
			 var _control:IControl = controls[controlId] as IControl;
			 return _control!=null;
			
		}
		public function getControl(controlId:String):IControl{
			 var _control:IControl = controls[controlId] as IControl;
			 if(_control==null)
			 throw new Error("haven't registered control in Context");
			 return _control;
		}
		
		public function unRegisterControl(controlId:String):void{
			delete controls[controlId];
		}
		
		/**
		 * register model
		 */ 
		public function registerModel(modelId:String, model:IModel):void{
			var _model:IModel = models[modelId] as IModel;
			if(_model!=null)
			 throw new Error("duplicate registering model in Context");
			models[modelId] = model;
		}
		
		public function getModel(modelId:String):IModel{
			var _model:IModel = models[modelId] as IModel;
			if(_model==null)
			 throw new Error("haven't registered  model in Context");
			return _model;
		}
		
		public function unRegisterModel(modelId:String):void{
			delete models[modelId];
		}
		
		
		public function unRegisterAll():void{
			/*
			for each(var v:UIComponent in components){
				components[v] = null;
			}*/
			for each(var c:IControl in controls){
				controls[c] = null;
			}
			for each(var m:IModel in models){
				models[m] = null;
			}
		}
		/*
		public function addInitRun(controlId:String):void{
			initRuns.push(controlId);
		}
		
		public function getInitRun():Array{
			return initRuns;
		}*/
		
		public function get cache():Array{
			return _cache;
		}
		
		/**
		 * send command in module
		 */ 
		public function sendCommand(commad:String, request:Object=null, response:Function=null):void{
			getControl(commad).execute(request, response);
		}
		/**
		 * send command in global scope
		 */ 
		public function sendCommandX(command:String, request:Object=null, response:Function=null):void{
			var mgr:ContextManager = ContextManager.getInstance();
			for each(var c:Context in mgr.getAllContexts()){
				if(c.existingControl(command)){
					var ctrl:IControl = c.getControl(command);
					if(ctrl!=null){
						ctrl.execute(request, response);
					}
				}
			}			
		}		
		
		public function putInSession(key:String, value:Object, scope:String="module"):void{
			var mgr:ContextManager = ContextManager.getInstance();
			if(scope!='application')
				cache[key] = value;
			else
			  mgr.cache[key] = value;
					
		}	
		public function getInSession(key:String, scope:String="module"):Object{
			var mgr:ContextManager = ContextManager.getInstance();
			if(scope!='application')
			{
				var value:Object = cache[key];
				if(value==null)
				  value = mgr.cache[key];
				return value;
			}	
			else
			   return mgr.cache[key];
		}
			
		public function removeInSession(key:String, scope:String="module"):void{
			var mgr:ContextManager = ContextManager.getInstance();
			if(scope!='application')
				cache[key]=null;
			else
			    mgr.cache[key]=null;
		}
		
				
		
		public function onload():void{			
			//auto run
			for(var i:int = 0;i<this.initRuns.length;i++){
			  var controlId:String =  initRuns[i] as String;
			  var control:IControl = controls[controlId] as IControl;
			  control.execute();				
			}
		}
				 
		
	}
}